package cas;

import lombok.SneakyThrows;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.math.BigDecimal;

/**
 * @author ZhuQi
 * @ClassName Demo1
 * @Date 2022/9/15 15:41
 * @Version 1.0
 * @Description 测试 比较替换成不同的类型
 */
public class Demo1 {
    // 需要反射一个unsafe类,jdk不允许直接获取这个对象实例
    static Unsafe unsafe = null;

    // 值
    static volatile BigDecimal state = new BigDecimal("0.01");

    // state偏移量
    static long offset;

    static {
        try {
            Field field = Unsafe.class.getDeclaredFields()[0];
            field.setAccessible(true);
            try {
                //反射出对象
                unsafe = (Unsafe) field.get(null);
                //获取属性的偏移量
                offset = unsafe.staticFieldOffset(Demo1.class.getDeclaredField("state"));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    @SneakyThrows
    public static void main(String[] args) {
        // test1();

        offsetTest();
    }

    private static void offsetTest() throws NoSuchFieldException {
        System.out.println("旧偏移量：" + offset + " --- " + "旧值：" + state);
        Demo1 demo1 = new Demo1();
        // 静态变量需要 class 对象
        boolean flag = unsafe.compareAndSwapObject(demo1.getClass(), offset, state, new BigDecimal("100.00"));
        System.out.println(flag);
        long state = unsafe.staticFieldOffset(demo1.getClass().getDeclaredField("state"));
        System.out.println("新偏移量：" + state + " --- " + "新值：" + Demo1.state);
    }

    /**
     * 测试比较替换成不同的类型
     */
    private static void test1() {
        Demo1 demo1 = new Demo1();
        boolean b = unsafe.compareAndSwapObject(demo1, offset, Demo1.state, new Integer(1));
        System.out.println(b);
        b = unsafe.compareAndSwapObject(demo1, offset, Demo1.state, new BigDecimal("1111"));
        System.out.println(b);
    }
}
